package com.gmall.data.service;

import com.gmall.data.api.UserActionCountQueryService;
import com.gmall.data.pojo.LogBean;
import com.gmall.data.pojo.RuleAtomicParam;
import com.gmall.data.pojo.RuleParam;
import com.gmall.data.utils.RuleUtil;
import org.apache.flink.api.common.state.ListState;

import java.util.List;

/**
 * 用户行为次序条件：在flink的state中统计行为次数
 */
public class UserActionCountQueryServiceImpl implements UserActionCountQueryService {

    ListState<LogBean> eventState;

    /**
     * 构造还函数，用device的ListState来初始化eventState
     *
     * @param eventState
     */
    public UserActionCountQueryServiceImpl(ListState<LogBean> eventState) {
        this.eventState = eventState;
    }


    /**
     * 查询规则参数列表中，要求的用户行为次序条件是否满足
     * 同时，将查询到的真实次数，set回 规则参数对象中
     *
     * @param deviceId
     * @param ruleParam 规则整体参数对象
     * @return 规则是否满足
     */
    @Override
    public boolean queryActionCounts(String deviceId, RuleParam ruleParam) {

        try {
            // 1.取出用户行为次数条件
            List<RuleAtomicParam> userActionCountParams = ruleParam.getUserActionCountParams();

            // 2.取出状态数据
            Iterable<LogBean> logBeans = eventState.get();

            queryActionCountsHelper(logBeans, userActionCountParams);

            // 经过上面的方法执行后，每一个原子条件中，都拥有了一个真实发生次数，我们在此判断是否每个原子条件都满足
            for (RuleAtomicParam userActionCountParam : userActionCountParams) {
                if (userActionCountParam.getRealCnt() < userActionCountParam.getCnt())
                    return false;
            }
            // 如果到达这一句话，说明上面的判断中，每个原子条件都满足，则返回整体结果true
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    private static void queryActionCountsHelper(Iterable<LogBean> logBeans, List<RuleAtomicParam> userActionCountParams) {
        try {
            // 对明细事件遍历
            for (LogBean logBean : logBeans) {
                for (RuleAtomicParam userActionCountParam : userActionCountParams) {

                    // 判断当前logBean和当前原子条件中的事件属性是否一致
                    boolean isMatch = RuleUtil.logBeanMathParam(logBean, userActionCountParam);

                    // 如果一致，则查询次数结果 + 1
                    if (isMatch)
                        userActionCountParam.setRealCnt(userActionCountParam.getRealCnt() + 1);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public boolean queryActionCounts(String deviceId, RuleAtomicParam atomicParam, String ruleId) {
        return false;
    }
}
